/*
 * @Author: szx
 * @Date: 2023-03-31 13:54:27
 * @LastEditTime: 2023-04-01 16:08:35
 * @Description:
 * @FilePath: \learn\fullstackopen\bloglist-part5\src\App.js
 */
import { useState, useEffect, useRef } from 'react'
import { getAll, create, update, setToken, deleteBlog } from './services/blogs'
import Login from './components/Login'
import loginService from './services/login'
import PostForm from './components/PostForm'
import { Notification, ErrorMessage } from './components/Notification'
import Togglable from './components/Togglable'
import BlogList from './components/BlogList'
const App = () => {
    const [blogs, setBlogs] = useState([])
    const [username, setUsername] = useState('')
    const [password, setPassword] = useState('')
    const [user, setUser] = useState(null)
    const [notification, setNotification] = useState(null)
    const [errorMessage, setErrorMessage] = useState(null);

    const blogFormRef = useRef()


    useEffect(() => {
        const loggedUserJSON = window.localStorage.getItem('loggedBlogUser')
        if (loggedUserJSON) {
            const user = JSON.parse(loggedUserJSON)
            setUser(user)
            setToken(user.token)
        }
        async function fetchData() {
            try {
                const blogs = await getAll();
                setBlogs(blogs)
            } catch (error) {
                setToken(null);
                window.localStorage.removeItem('loggedBlogUser')
                setUser(null)
            }
        }
        fetchData()

    }, [])


    const handleLogin = async (event) => {
        event.preventDefault()
        try {
            const user = await loginService({
                username, password,
            })
            console.log(user)
            window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))
            setToken(user.token)
            setUser(user)
            setUsername('')
            setPassword('')
        } catch (exception) {
            setErrorMessage('Wrong credentials')
            console.log(exception)
            setTimeout(() => {
                setErrorMessage(null)
            }, 5000)
        }
    }

    const hangdleLogout = () => {
        window.localStorage.removeItem('loggedBlogUser')
        setUser(null)
    }

    const addBlog = async (newBlogObject) => {
        blogFormRef.current.toggleVisibility()

        const newBlog = await create(newBlogObject);
        if (newBlog) {
            setBlogs(blogs.concat(newBlog));
            setNotification(`a new blog 《${newBlog.title}》 added`);
        }
    }

    const handleLikes = (blog) => {
        return async () => {
            const likedBlog = await update(blog.id, { ...blog, likes: blog.likes + 1, user: blog.user.id.toString() })
            setBlogs(blogs.map(blog =>
                blog.id === likedBlog.id ? likedBlog : blog
            ))
        }
    }

    const handleBlogDelete = (blog) => {
        return async () => {
            if (window.confirm(`Remove ${blog.title} by ${blog.author}?`)) {
                await deleteBlog(blog.id)
                setBlogs(
                    blogs.filter(currnetBlog => currnetBlog.id !== blog.id)
                )
            }
        }

    }
    const handleUsername = ({ target }) => setUsername(target.value)
    const handlePassword = ({ target }) => setPassword(target.value)


    if (user === null) {

        return (
            <div>
                <ErrorMessage error={errorMessage} />
                <Login handleLogin={handleLogin} handleUsername={handleUsername} handlePassword={handlePassword} username={username} password={password} />
            </div>
        )
    } else {
        return (
            <div>
                <h2>blogs</h2>

                <Notification notification={notification} />

                <div>
                    <p>{user.name} logged in <button onClick={hangdleLogout}>Logout</button></p>
                </div>

                <Togglable buttonLabel="new Blog" ref={blogFormRef}>
                    <PostForm addBlog={addBlog} />
                </Togglable>

                <BlogList blogs={blogs.sort((a, b) => b.likes - a.likes)} handleLikes={handleLikes} loggedUser={user.id} handleBlogDelete={handleBlogDelete} />
            </div>
        )
    }
}

export default App